package cn.iocoder.yudao.module.alipay.util;

import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicHeader;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;


/**

 * httpclient 工具类

 * @author tian.hq 2019.05.31

 *

 */

@Slf4j
public class HttpUtils {

    private static final int timeOut = 100 * 1000;

    /**

     * 创建httpClient 对象

     * @return

     */
    private static Registry getDefaultRegistry() {

        return RegistryBuilder.create()

                .register("http", PlainConnectionSocketFactory.getSocketFactory())

                .register("https", SSLConnectionSocketFactory.getSocketFactory())

                .build();
    }

    /**

     * httpClient 发送post请求

     * @param client

     * @param url

     * @param params

     * @return 返回

     * @throws Exception

     */

    public static String sendPost(HttpClient client,String url,Map params) throws Exception {

        HttpPost httppost = new HttpPost(url);

        config(httppost);

        setPostParams(httppost, params);

        HttpResponse response = null;

        try {

            response = client.execute(httppost);

            HttpEntity entity = response.getEntity();

            String result = EntityUtils.toString(entity, "utf-8");

            EntityUtils.consume(entity);

            return result;

        } catch (Exception e) {
            throw e;

        }

    }

    /**
     * get请求，组装url，放入鉴权header
     * 返回值RestDataResponse为自定义javaBean,结构与返回值Json字符型保持一致
     */
    public static String createGet(String url){
        Request request = new  Request.Builder()
                .url(url)
                .addHeader("Content-Type", "application/x-www-form-urlencoded;charset:utf-8;").build();
        // new client对象时注意配置的链接与超时时间，根据需要进行调整
        OkHttpClient client = new OkHttpClient.Builder()
                .connectTimeout(1, TimeUnit.SECONDS)
                .readTimeout(3, TimeUnit.SECONDS)
                .build();

        try{
            Response response = client.newCall(request).execute();
            String body = response.body().string();
            return body;
            //json字符串转javaBean

        }catch (Exception e){
            return null;
        }
    }


    /**
     * 发送post请求
     * @param json
     * @param URL
     * @return
     */
    public static String sendPost(JSONObject json, String URL) {
        CloseableHttpClient client = HttpClients.createDefault();
        HttpPost post = new HttpPost(URL);

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.MULTIPART_FORM_DATA);
        post.setHeader("Content-Type", "application/form-data");

        //post.addHeader("Authorization", "Basic YWRtaW46");
        String result;
        try {
            StringEntity s = new StringEntity(json.toString(), "utf-8");
            s.setContentType(new BasicHeader(HTTP.CONTENT_TYPE,
                    "application/json"));
            post.setEntity(s);
            // 发送请求
            HttpResponse httpResponse = client.execute(post);
            // 获取响应输入流
            InputStream inStream = httpResponse.getEntity().getContent();
            BufferedReader reader = new BufferedReader(new InputStreamReader(
                    inStream, "utf-8"));
            StringBuilder strber = new StringBuilder();
            String line;
            while ((line = reader.readLine()) != null)
                strber.append(line + "\n");
            inStream.close();
            result = strber.toString();
            if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                System.out.println("请求服务器成功，做相应处理");
            } else {
                System.out.println("请求服务端失败");
            }
        } catch (Exception e) {
            log.error("请求异常："+e.getMessage());
            throw new RuntimeException(e);
        }
        return result;
    }


    public static String sendPost(String url,String data) throws Exception {
        CloseableHttpClient httpclient = HttpClients.createDefault();
        HttpPost httppost = new HttpPost(url);
        config(httppost);

        StringEntity stringEntity = new StringEntity(data,Charset.forName("UTF-8"));

        httppost.setEntity(stringEntity);

        HttpResponse response = null;

        try {

            response = httpclient.execute(httppost);

            HttpEntity entity = response.getEntity();

            String result = EntityUtils.toString(entity, "UTF-8");

            EntityUtils.consume(entity);

            return result;

        } catch (Exception e) {
            throw e;
        }

    }

    /***
     * 发送post 请求 ，附带header信息
     * @param url
     * @param data
     * @param headers
     * @return
     * @throws Exception
     */

    public static String sendPost(String url,String data,Map headers) throws Exception {
        CloseableHttpClient client = HttpClients.createDefault();
        HttpPost httppost = new HttpPost(url);
        config(httppost);
        fillHttpPostHeader(httppost,headers);
        StringEntity stringEntity = new StringEntity(data,Charset.forName("UTF-8"));
        httppost.setEntity(stringEntity);
        HttpResponse response = null;
        try {
            response = client.execute(httppost);
            HttpEntity entity = response.getEntity();
            String result = EntityUtils.toString(entity, "UTF-8");
            EntityUtils.consume(entity);
            return result;
        } catch (Exception e) {
            throw e;
        }
    }

    private static void setPostParams(HttpPost httpost, Map params) {
        List nvps = new ArrayList();

        Set keySet = params.keySet();

        for (Object key : keySet) {
            nvps.add(new BasicNameValuePair((String)key, params.get(key).toString()));
        }
        try {

            httpost.setEntity(new UrlEncodedFormEntity(nvps, "UTF-8"));

        } catch (UnsupportedEncodingException e) {

            e.printStackTrace();


        }

    }

    private static void config(HttpRequestBase httpRequestBase) {

// 配置请求的超时设置

        RequestConfig requestConfig = RequestConfig.custom()

                .setConnectionRequestTimeout(timeOut)

                .setConnectTimeout(timeOut).setSocketTimeout(timeOut).build();

        httpRequestBase.setConfig(requestConfig);

    }

    /**

     * 为HttpPost添加header信息

     * @param post

     * @param headers

     */

    private static void fillHttpPostHeader(HttpPost post,Map headers){

        if(headers == null){

            return ;

        }

        for(Object key:headers.keySet()){

            post.addHeader((String) key, (String) headers.get(key));

        }

    }

}

